package cn.hznc.controller.service.message;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.controller.service.process.ProcessManageService;
import cn.hznc.controller.service.schedule.ToolScheduleService;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.message.GetMessageReq;
import cn.hznc.domain.request.message.SelectUserByConditionReq;
import cn.hznc.domain.request.message.SendMessageReq;
import cn.hznc.domain.request.process.UnmetToolReqReload;
import cn.hznc.domain.response.PageResult;
import cn.hznc.exception.ToolManageEx;
import cn.hznc.exception.ToolManageException;
import cn.hznc.exception.UserEx;
import cn.hznc.exception.UserException;
import cn.hznc.mapper.MessageMapper;
import cn.hznc.mapper.OrderCraftMapper;
import cn.hznc.mapper.OrderMapper;
import cn.hznc.repository.MachineToolTaskRespository;
import cn.hznc.repository.OrderRespository;
import cn.hznc.repository.UserRepository;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.CraftParamVo;
import cn.hznc.vo.ToolDemandPredictionVo;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：Administrator
 * @Date：2023/10/23 14:18
 */
@Service
public class MessageService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderRespository orderRespository;

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private ProcessManageService processManageService;

    @Resource
    private ToolScheduleService toolScheduleService;

    @Resource
    private UserRepository userRepository;

    @Resource
    private MachineToolTaskRespository machineToolTaskRespository;

    @Resource
    private OrderCraftMapper orderCraftMapper;


    /**
     * 消息类型为1时  对应的推送人员列表
     */
    private static final List<String> messageType1List = new ArrayList<>();

    /**
     * 消息类型为2时  对应的推送人员列表
     */
    private static final List<String> messageType2List = new ArrayList<>();

    /**
     * 消息类型为3时  对应的推送人员列表
     */
    private static final List<String> messageType3List = new ArrayList<>();

    /**
     * 消息类型为4时  对应的推送人员列表
     */
    private static final List<String> messageType4List = new ArrayList<>();

    private static final String ORDER_TASK_ID = "生产订单号";

    private static final String ORDER_RELEASE_OFFSET = "已下达，请尽快分配任务";

    private static final String MATERIAL_NO = "物料编码:";

    private static final String CRAFT_SEQ = "工序序号:";

    private static final String CRAFT_NAME = "工序名:";


    static {
        messageType1List.add("生产计划人员");

        messageType2List.add("工艺人员");

        messageType3List.add("刀具组装人员");

        messageType4List.add("版组长/操作工");
    }

    public Object releasedOrderMessage(List<Integer> conditions) {
        QueryWrapper<OrderEntity> wrapper = new QueryWrapper<>();
        if (CollectionUtil.isNotEmpty(conditions) && conditions.contains(1)) {
            wrapper.eq("abutment_status", 5);
        }
        List<OrderEntity> orderEntities = orderMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(conditions) && CollectionUtil.isNotEmpty(orderEntities)) {
            //orderEntities = orderEntities.stream().filter(this::filterOrderEntities).collect(Collectors.toList());
            orderEntities = filterByConditions(orderEntities, conditions);
        }
        if (CollectionUtil.isEmpty(orderEntities)) {
            return Boolean.TRUE;
        }
        //查询所有计划消息
        List<MessageEntity> messageEntities = getMessageEntities(1);
        List<String> taskIds = messageEntities.stream().map(MessageEntity::getTaskId).collect(Collectors.toList());
        //已下达的工单列表
        List<MessageEntity> insertList = new ArrayList<>();
        orderEntities.forEach(orderEntity -> {
            if (taskIds.contains(orderEntity.getTaskId())) {
                return;
            }
            MessageEntity messageEntity = new MessageEntity();
            messageEntity.setMessageType(1);
            messageEntity.setStatus(0);
            messageEntity.setCreateTime(new Date());
            messageEntity.setContent(ORDER_TASK_ID + orderEntity.getTaskId() + ORDER_RELEASE_OFFSET);
            messageEntity.setTaskId(orderEntity.getTaskId());
            messageEntity.setConnectRoles(JSONArray.toJSONString(messageType1List));
            insertList.add(messageEntity);
        });

        if (CollectionUtil.isNotEmpty(insertList)) {
            messageMapper.insertBatchSomeColumn(insertList);
        }
        return Boolean.TRUE;
    }

    private List<MessageEntity> getMessageEntities(Integer type) {
        QueryWrapper<MessageEntity> messageWrapper = new QueryWrapper<>();
        messageWrapper.eq("message_type", type);
        messageWrapper.ne("status", 1);
        ;
        return messageMapper.selectList(messageWrapper);
    }

    private List<MessageEntity> getMessageEntitiesReload(Integer type, Integer machineToolTaskId) {
        QueryWrapper<MessageEntity> messageWrapper = new QueryWrapper<>();
        messageWrapper.eq("message_type", type);
        messageWrapper.eq("machine_tool_task_id", machineToolTaskId);
        messageWrapper.ne("status", 1);
        return messageMapper.selectList(messageWrapper);
    }

    private boolean filterOrderEntities(OrderEntity orderEntity) {
        //查询工单对应的所有子工序
        QueryWrapper<OrderCraftEntity> orderCraftWrapper = new QueryWrapper<>();
        orderCraftWrapper.eq("task_id", orderEntity.getTaskId());
        OrderCraftEntity orderCraftEntity = orderCraftMapper.selectOne(orderCraftWrapper);
        if (ObjectUtil.isNotNull(orderCraftEntity) && StringUtil.isNotEmpty(orderCraftEntity.getCraftParam()) && !"[]".equals(orderCraftEntity.getCraftParam())) {
            List<CraftParamVo> craftParamVos = JSONArray.parseArray(orderCraftEntity.getCraftParam(), CraftParamVo.class);
            if (CollectionUtil.isNotEmpty(craftParamVos)) {
                for (CraftParamVo craftParamVo : craftParamVos) {
                    if (StringUtils.isNotBlank(craftParamVo.getPlanTime()) && craftParamVo.getStatus() == 5 && (craftParamVo.getName().contains("五轴铣削加工中心") || craftParamVo.getName().contains("三四轴加工中心"))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private List<OrderEntity> filterByConditions(List<OrderEntity> orderEntities, List<Integer> conditions) {
        conditions = conditions.stream().filter(integer -> integer != 1).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(conditions)) {
            orderEntities.forEach(orderEntity -> {
                QueryWrapper<OrderCraftEntity> orderCraftWrapper = new QueryWrapper<>();
                orderCraftWrapper.eq("task_id", orderEntity.getTaskId());
                OrderCraftEntity orderCraftEntity = orderCraftMapper.selectOne(orderCraftWrapper);
                if (ObjectUtil.isNotNull(orderCraftEntity) && StringUtil.isNotEmpty(orderCraftEntity.getCraftParam()) && !"[]".equals(orderCraftEntity.getCraftParam())) {
                    List<CraftParamVo> craftParamVos = JSONArray.parseArray(orderCraftEntity.getCraftParam(), CraftParamVo.class);
                    orderEntity.setCraftParamVos(craftParamVos);
                }else{
                    orderEntity.setCraftParamVos(new ArrayList<>());
                }
            });
            for (Integer condition : conditions) {
                if(condition ==2){
                    orderEntities = filterByCraftPlanTime(orderEntities);
                }else if(condition ==3){
                    orderEntities = filterByCraftStatus(orderEntities);
                }else if(condition==4){
                    orderEntities = filterByCraftName(orderEntities);
                }
            }
        }
        return orderEntities;
    }

    private List<OrderEntity> filterByCraftName(List<OrderEntity> orderEntities) {
        return orderEntities
                .stream()
                .filter(orderEntity -> {
                    if(CollectionUtil.isEmpty(orderEntity.getCraftParamVos())){
                        return false;
                    }
                    for (CraftParamVo craftParamVo : orderEntity.getCraftParamVos()) {
                        if ((craftParamVo.getName().contains("五轴铣削加工中心") || craftParamVo.getName().contains("三四轴铣削加工中心"))) {
                            return true;
                        }
                    }
                    return false;
                }).collect(Collectors.toList());
    }

    private List<OrderEntity> filterByCraftStatus(List<OrderEntity> orderEntities) {
        return orderEntities
                .stream()
                .filter(orderEntity -> {
                    if(CollectionUtil.isEmpty(orderEntity.getCraftParamVos())){
                        return false;
                    }
                    for (CraftParamVo craftParamVo : orderEntity.getCraftParamVos()) {
                        if (craftParamVo.getStatus() == 5) {
                            return true;
                        }
                    }
                    return false;
                }).collect(Collectors.toList());
    }

    private List<OrderEntity> filterByCraftPlanTime(List<OrderEntity> orderEntities) {
        return orderEntities
                .stream()
                .filter(orderEntity -> {
                    if(CollectionUtil.isEmpty(orderEntity.getCraftParamVos())){
                        return false;
                    }
                    for (CraftParamVo craftParamVo : orderEntity.getCraftParamVos()) {
                        if (StringUtils.isNotBlank(craftParamVo.getPlanTime())) {
                            return true;
                        }
                    }
                    return false;
        }).collect(Collectors.toList());
    }

    public Object programMessage(String taskId) {
        List<MessageEntity> insertList = new ArrayList<>();
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectByTaskIds(taskId);
        //获取工艺人员消息
        List<MessageEntity> messageEntities = getMessageEntities(2);
        List<Integer> machineToolTaskIds = messageEntities
                .stream()
                .map(MessageEntity::getMachineToolTaskId)
                .collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
            machineToolTaskEntities.forEach(machineToolTaskEntity -> {
                String materialNo = orderRespository.selectMaterialNoByTaskId(machineToolTaskEntity.getOrderTaskId());
                if (machineToolTaskIds.contains(machineToolTaskEntity.getId())
                        || processManageService.queryProgramStatus(materialNo, machineToolTaskEntity.getContent(), machineToolTaskEntity.getMachineToolId())) {
                    return;
                }
                //程序缺失逻辑判断
                MessageEntity messageEntity = new MessageEntity();
                messageEntity.setMessageType(2);
                messageEntity.setStatus(0);
                messageEntity.setCreateTime(new Date());
                messageEntity.setContent(
                        "已分配任务(" +
                                ORDER_TASK_ID + machineToolTaskEntity.getOrderTaskId()//工单号
                                + "-" + MATERIAL_NO + materialNo//物料编码
                                + "-" + CRAFT_SEQ + machineToolTaskEntity.getOrderSnapshotCraftSeq()//工单工序号
                                + "-" + CRAFT_NAME + machineToolTaskEntity.getCraftName()//工序名
                                + ")缺失程序");
                messageEntity.setMachineToolTaskId(machineToolTaskEntity.getId());
                messageEntity.setConnectRoles(JSONArray.toJSONString(messageType2List));
                insertList.add(messageEntity);
            });
        }
        if (CollectionUtil.isNotEmpty(insertList)) {
            messageMapper.insertBatchSomeColumn(insertList);
        }
        return Boolean.TRUE;
    }

    public Object unmetToolListMessage() {
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectByTaskIds("");
        //toolScheduleService.getUnmetToolList()
        List<MessageEntity> messageEntities = getMessageEntities(3);
        if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
            machineToolTaskEntities = machineToolTaskEntities
                    .stream()
                    .filter(machineToolTaskEntity -> {
                String materialNo = orderRespository.selectMaterialNoByTaskId(machineToolTaskEntity.getOrderTaskId());
                return processManageService.queryProgramStatus(materialNo, machineToolTaskEntity.getContent(), machineToolTaskEntity.getMachineToolId());
            }).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(machineToolTaskEntities) && CollectionUtil.isEmpty(messageEntities)) {
                List<Integer> ids = machineToolTaskEntities.stream().map(MachineToolTaskEntity::getId).collect(Collectors.toList());
                UnmetToolReqReload unmetToolReqReload = new UnmetToolReqReload();
                unmetToolReqReload.setFlag(true);
                unmetToolReqReload.setPageNum(1);
                unmetToolReqReload.setPageSize(10);
                List<ToolDemandPredictionVo> unmetToolListReload = toolScheduleService.getUnmetToolListReload(unmetToolReqReload);
                if (CollectionUtil.isNotEmpty(unmetToolListReload) && CollectionUtil.isEmpty(messageEntities)) {
                    QueryWrapper<MessageEntity> wrapper = new QueryWrapper<>();
                    wrapper.eq("message_type", 3);
                    messageMapper.delete(wrapper);
                    MessageEntity messageEntity = new MessageEntity();
                    messageEntity.setMessageType(3);
                    messageEntity.setStatus(0);
                    messageEntity.setCreateTime(new Date());
                    messageEntity.setContent("存在未满足刀具需要备刀");
                    messageEntity.setConnectRoles(JSONArray.toJSONString(messageType3List));
                    messageMapper.insert(messageEntity);
                }
            }
        }
        return Boolean.TRUE;
    }

    public Object getMessageList(GetMessageReq getMessageReq) {
        Integer userId = getMessageReq.getUserId();
        List<MessageEntity> resultList = getMessageEntities(getMessageReq, userId);
        List<MessageEntity> pageList;
        pageList = CommonUtil.pageList(resultList, getMessageReq.getPageNum(), getMessageReq.getPageSize());
        //List<RolesEntity> rolesEntityList = userRepository.selectbyRolseId()
        return new PageResult<>(pageList, (long) resultList.size());
    }

    private List<MessageEntity> getMessageEntities(GetMessageReq getMessageReq, Integer userId) {
        List<String> rolses = userRepository.selectRolesByUId(userId);
        if (StringUtil.isNotEmpty(getMessageReq.getRole())) {
            rolses = rolses.stream().filter(s -> s.equals(getMessageReq.getRole())).collect(Collectors.toList());
            getMessageReq.setRoles(rolses);
        }
        getMessageReq.setMessageTypes(userRepository.selectTypes(rolses, getMessageReq.getMessageType()));
        List<MessageEntity> resultList = userRepository.selectUserMessage(getMessageReq);
        List<MessageEntity> pageList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(rolses) && rolses.contains("班组长/操作工")) {
            //包含就过滤
            resultList = resultList.stream().filter(messageEntity -> filterMessage(messageEntity, userId)).collect(Collectors.toList());
        }
        return resultList;
    }

    private boolean filterMessage(MessageEntity messageEntity, Integer userId) {
        if (messageEntity.getMessageType() != 4) {
            return true;
        }
        if (ObjectUtil.isNotNull(messageEntity.getConnectOperator()) || StringUtil.isNotEmpty(messageEntity.getConnectOperator())) {
            List<Integer> userIds = JSONArray.parseArray(messageEntity.getConnectOperator(), Integer.class);
            if (CollectionUtil.isNotEmpty(userIds) && userIds.contains(userId)) {
                return true;
            }
        }
        return false;
    }

    public Object getToolMessage(Integer id) {
        List<MessageEntity> messageEntities = getMessageEntitiesReload(4, id);
        if (CollectionUtil.isNotEmpty(messageEntities)) {
            return Boolean.TRUE;
        }
        List<ToolDemandPredictionVo> toolDemandPredictionVos = toolScheduleService.getToolListMessage(1, 100, Arrays.asList(id));
        if (CollectionUtil.isNotEmpty(toolDemandPredictionVos)) {
            List<String> statusList = toolDemandPredictionVos.stream().map(ToolDemandPredictionVo::getStatus).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(statusList) && !statusList.contains("未满足")) {
                if (flag(statusList)) {
                    MachineToolTaskEntity machineToolTaskEntity = machineToolTaskRespository.selectById(id);
                    MessageEntity messageEntity = new MessageEntity();
                    messageEntity.setMessageType(4);
                    messageEntity.setStatus(0);
                    messageEntity.setCreateTime(new Date());
                    messageEntity.setMachineToolTaskId(id);
                    //查询任务对应排班人员
                    List<Integer> ids = machineToolTaskRespository.selectCurrentEmployee(machineToolTaskEntity.getMachineToolName(), new Date());
                    if (CollectionUtil.isNotEmpty(ids)) {
                        messageEntity.setConnectOperator(JSONArray.toJSONString(ids));
                    }
                    messageEntity.setContent("已分配任务(" +
                            ORDER_TASK_ID + machineToolTaskEntity.getOrderTaskId()//工单号
                            + "-" + CRAFT_SEQ + machineToolTaskEntity.getOrderSnapshotCraftSeq()//工单工序号
                            + "-" + CRAFT_NAME + machineToolTaskEntity.getCraftName()//工序名
                            + ")可以取刀");
                    messageEntity.setConnectRoles(JSONArray.toJSONString(messageType4List));
                    messageMapper.insert(messageEntity);
                }
            }
        }
        return Boolean.TRUE;
    }

    private boolean flag(List<String> statusList) {
        for (String s : statusList) {
            if (s.equals("未满足")) {
                return false;
            }
        }
        if (!statusList.contains("2")) {
            return false;
        }
        return true;
    }

    public Object editMessageStatus(MessageEntity messageEntity) {
        if(ObjectUtil.isNotNull(messageEntity) && messageEntity.getStatus()==1 && ObjectUtil.isNotNull(messageEntity.getReadId())){
            UserEntity userEntity = userRepository.selectbyUserid(messageEntity.getReadId());
            if(ObjectUtil.isNotNull(userEntity)){
                messageEntity.setReceiveTime(new Date());
                messageEntity.setReadId(messageEntity.getReadId());
                messageEntity.setReadName(userEntity.getEmployeeName());
            }
        }
        messageMapper.updateById(messageEntity);
        return Boolean.TRUE;
    }

    public Object sendMessage(SendMessageReq sendMessageReq) throws ToolManageException {
        if(ObjectUtil.isNull(sendMessageReq.getMessageType())){
            throw new ToolManageException(ToolManageEx.NO_MESSAGE_TYPE.getCode() , ToolManageEx.NO_MESSAGE_TYPE.getMsg());
        }
        //校验是否有发送权限
        List<String> roles = userRepository.selectRolesByUId(sendMessageReq.getSenderId());
        //查询该用户可以使用的消息类型
        List<Integer> messageTypes =  userRepository.selectMessageTypeByRoles(roles);
        if(CollectionUtil.isEmpty(messageTypes) || !messageTypes.contains(sendMessageReq.getMessageType())){
            throw new ToolManageException(ToolManageEx.PERMISSION_DENIED.getCode(), ToolManageEx.PERMISSION_DENIED.getMsg());
        }
        List<MessageEntity> insertList = new ArrayList<>();
        //构建消息内容
        UserEntity senderEntity = userRepository.selectbyUseridReload(sendMessageReq.getSenderId());
        if(CollectionUtil.isNotEmpty(sendMessageReq.getReceiverId())){
            sendMessageReq.getReceiverId().forEach(integer -> {
                UserEntity receiverEntity = userRepository.selectbyUseridReload(integer);
                MessageEntity messageEntity = new MessageEntity();
                if(ObjectUtil.isNotNull(senderEntity)){
                    messageEntity.setSenderId(senderEntity.getId());
                    messageEntity.setSenderName(senderEntity.getEmployeeName());
                }
                if(ObjectUtil.isNotNull(receiverEntity)){
                    messageEntity.setReceiverId(receiverEntity.getId());
                    messageEntity.setReceiverName(receiverEntity.getEmployeeName());
                }
                messageEntity.setMessageType(sendMessageReq.getMessageType());
                messageEntity.setStatus(0);
                messageEntity.setSendTime(new Date());
                messageEntity.setContent(sendMessageReq.getMessageContent());
                messageEntity.setCreateTime(new Date());
                insertList.add(messageEntity);
            });
        }
        if(CollectionUtil.isNotEmpty(insertList)){
            messageMapper.insertBatchSomeColumn(insertList);
        }
        return Boolean.TRUE;
    }

    public Object qryMessageTypeByUserId(Integer userId) throws UserException {
        if(ObjectUtil.isNull(userId)){
            throw new UserException(UserEx.USERNAME_NOT_EXIST.getCode(), UserEx.USERNAME_NOT_EXIST.getCode());
        }
        return  userRepository.qryMessageTypeByUserId(userId);
    }

    public Object selectUserByCondition(SelectUserByConditionReq selectUserByConditionReq) {
        if(CollectionUtil.isEmpty(selectUserByConditionReq.getMessageTypes())){
            return new ArrayList<>();
        }
        //查询消息对应的角色列表
        List<String> rolesName = userRepository.selectByMessageTypes(selectUserByConditionReq.getMessageTypes());
        //查询用户列表以及对应的角色列表
        List<EmployeeEntity> userEntities = userRepository.selectAllUserList();
        if(CollectionUtil.isNotEmpty(userEntities)){
            userEntities.forEach(employeeEntity -> {
                employeeEntity.setRoleNames(userRepository.selectRolesByUId(employeeEntity.getUserId()));
            });
            userEntities = userEntities.stream().filter(employeeEntity -> {
                List<String> roleNames = employeeEntity.getRoleNames();
                if(CollectionUtil.isEmpty(roleNames)){
                    return false;
                }
                for (String roleName : roleNames) {
                    if(rolesName.contains(roleName)){
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
        }
        return userEntities;
    }
}
